home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / yk211src.lha / Yak_2.11_Src / WBStartup / Unixdirs.c < prev    next >
C/C++ Source or Header  |  1995-10-18  |  15KB  |  516 lines

  1. /*
  2.  ** Patches dos.library functions to allow use of '.' and '..' ala UNIX.
  3.  ** Largely inspired from UnixDirsII from Martin Scott.
  4.  **
  5.  ** List of patched functions :
  6.  **
  7.  **     AssignLate
  8.  **     AssignPath
  9.  **     CreateDir
  10.  **     DeleteFile
  11.  **     LoadSeg
  12.  **     Lock
  13.  **     MakeLink
  14.  **     MatchFirst
  15.  **     NewLoadSeg
  16.  **     Open
  17.  **     ParsePattern
  18.  **     Rename
  19.  **     SetComment
  20.  **     SetFileDate
  21.  **     SetProtection
  22.  **
  23.  ** Author: Gael Marziou
  24.  ** Created: 14 July 94 (Bastille day ;-)
  25.  **
  26.  **
  27.  */
  28.  
  29. #define __USE_SYSBASE
  30.  
  31. #include <exec/types.h>
  32. #include <exec/execbase.h>
  33. #include <exec/memory.h>
  34. #include <exec/semaphores.h>
  35. #include <dos/dos.h>
  36. #include <libraries/commodities.h>
  37. #include <string.h>
  38. #include <proto/dos.h>
  39. #include <proto/exec.h>
  40.  
  41. #include "Patch_Libs.h"
  42. #include "yak.h"
  43. #include "Settings.h"
  44.  
  45. /* Local protos */
  46. SAVEDS BOOL adjustpath(UBYTE *path, UBYTE *newpath, LONG len);
  47.  
  48. /* The number of 'replacement' functions for UnixDirs feature */
  49. #define UNIXDIRS_NUMBEROFFUNCTIONS (15)
  50.  
  51. /* declare stuff for standard one-parameter function */
  52. /* UBYTE * in d1 */
  53. #define DEC11_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(a6) struct Library *base)
  54. #define DEC11_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(a6) struct Library *base)
  55. #define DEC11(name) DEC11_OLD(old## name); DEC11_NEW(new## name); DEC_LVO(LVO## name)
  56.  
  57. /* declare stuff for standard two-parameter function */
  58. /* UBYTE * in d1 */
  59. #define DEC21_OLD(oldname) LONG (*ASM oldname) (REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
  60. #define DEC21_NEW(newname) SAVEDS LONG ASM newname(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *base)
  61. #define DEC21(name) DEC21_OLD(old## name); DEC21_NEW(new## name); DEC_LVO(LVO## name)
  62.  
  63. /* declare stuff for standard two-parameter function */
  64. /* UBYTE * in d2 */
  65. #define DEC22_OLD(oldname) LONG (*ASM oldname) (REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
  66. #define DEC22_NEW(newname) SAVEDS LONG ASM newname(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *base)
  67. #define DEC22(name) DEC22_OLD(old## name); DEC22_NEW(new## name); DEC_LVO(LVO## name)
  68.  
  69. /* the patched functions themselves */
  70. DEC22(AssignLate);
  71. DEC22(AssignPath);
  72. DEC11(CreateDir);
  73. DEC11(DeleteFile);
  74. DEC11(LoadSeg);
  75. DEC21(Lock);
  76. DEC21(MatchFirst);
  77. DEC21(NewLoadSeg);
  78. DEC21(Open);
  79. DEC21(SetComment);
  80. DEC21(SetFileDate);
  81. DEC21(SetProtection);
  82.  
  83.  
  84. /* manually declared, because different from standard */
  85.  
  86. LONG (*ASM oldMakeLink) (REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
  87. SAVEDS LONG ASM newMakeLink(REG(d1) UBYTE *, REG(d2) LONG, REG(d3) LONG, REG(a6) struct Library *);
  88. extern LVOMakeLink;
  89.  
  90. LONG (*ASM oldRename) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
  91. SAVEDS LONG ASM newRename(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(a6) struct Library *);
  92. extern LVORename;
  93.  
  94. LONG (*ASM oldParsePattern) (REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
  95. SAVEDS LONG ASM newParsePattern(REG(d1) UBYTE *, REG(d2) UBYTE *, REG(d3) LONG, REG(a6) struct Library *);
  96. extern LVOParsePattern;
  97.  
  98. struct LVOTable LVOArrayUnixDirs[] =
  99. {
  100. {(LONG)&LVOCreateDir, (struct Library *)&DOSBase, (ULONG)&oldCreateDir, (ULONG)&newCreateDir },
  101. {(LONG)&LVODeleteFile, (struct Library *)&DOSBase, (ULONG)&oldDeleteFile, (ULONG)&newDeleteFile },
  102. {(LONG)&LVOLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldLoadSeg, (ULONG)&newLoadSeg },
  103.     
  104. {(LONG)&LVOLock, (struct Library *)&DOSBase, (ULONG)&oldLock, (ULONG)&newLock },
  105. {(LONG)&LVONewLoadSeg, (struct Library *)&DOSBase, (ULONG)&oldNewLoadSeg, (ULONG)&newNewLoadSeg },
  106. {(LONG)&LVOOpen, (struct Library *)&DOSBase, (ULONG)&oldOpen, (ULONG)&newOpen },
  107.     
  108. {(LONG)&LVOSetComment, (struct Library *)&DOSBase, (ULONG)&oldSetComment, (ULONG)&newSetComment },
  109. {(LONG)&LVOSetFileDate, (struct Library *)&DOSBase, (ULONG)&oldSetFileDate, (ULONG)&newSetFileDate },
  110.     
  111. {(LONG)&LVOSetProtection, (struct Library *)&DOSBase, (ULONG)&oldSetProtection, (ULONG)&newSetProtection },
  112. {(LONG)&LVOAssignLate, (struct Library *)&DOSBase, (ULONG)&oldAssignLate, (ULONG)&newAssignLate },
  113. {(LONG)&LVOAssignPath, (struct Library *)&DOSBase, (ULONG)&oldAssignPath, (ULONG)&newAssignPath },
  114. {(LONG)&LVORename, (struct Library *)&DOSBase, (ULONG)&oldRename, (ULONG)&newRename },
  115. {(LONG)&LVOMakeLink, (struct Library *)&DOSBase, (ULONG)&oldMakeLink, (ULONG)&newMakeLink },
  116. {(LONG)&LVOMatchFirst, (struct Library *) & DOSBase, (ULONG)&oldMatchFirst, (ULONG)&newMatchFirst },
  117. {(LONG)&LVOParsePattern, (struct Library *) & DOSBase, (ULONG)&oldParsePattern, (ULONG)&newParsePattern }
  118. };
  119.  
  120.  
  121. struct UnixDirsJumpTable
  122. {
  123.     struct SignalSemaphore jt_Semaphore;
  124.     UWORD pad_word;
  125.     struct Task *jt_Owner;
  126.     UBYTE jt_Function[UNIXDIRS_NUMBEROFFUNCTIONS * 6];
  127. };
  128.  
  129. /* Strings */
  130. /* The name this JumpTable/Semaphore will get. */
  131. static UBYTE *UnixDirsJTName = "YakUnixDirs-JT";
  132.  
  133. static BOOL UnixDirsPatchInstalled = FALSE;
  134.  
  135.  
  136. __regargs void
  137.     ToggleUnixDirs( BOOL toggle )
  138. {
  139.     if (toggle == TRUE)
  140.     {
  141.         if (UnixDirsPatchInstalled == FALSE)
  142.         {
  143.             InstallWedge(UnixDirsJTName, 
  144.                          LVOArrayUnixDirs, 
  145.                          (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
  146.             UnixDirsPatchInstalled = TRUE;
  147.         }
  148.     }
  149.     else
  150.     {
  151.         if (UnixDirsPatchInstalled == TRUE)
  152.         {
  153.             RemoveWedge(UnixDirsJTName, 
  154.                         LVOArrayUnixDirs, 
  155.                         (UBYTE) UNIXDIRS_NUMBEROFFUNCTIONS);
  156.             UnixDirsPatchInstalled = FALSE;
  157.         }
  158.     }
  159. }
  160.  
  161.  
  162. /******************************************************************************/
  163. /*******************                                 **************************/
  164. /*******************   NEW DOS ROUTINES START HERE   **************************/
  165. /*******************                                 **************************/
  166. /******************************************************************************/
  167.  
  168. /********************************************
  169.   
  170.   Example of the simplest patch (does nothing)
  171.   
  172.   SAVEDS LONG ASM
  173.   new(REG(d1) LONG arg1, REG(d2) LONG arg2,
  174.   REG(a6) struct Library *base)
  175.   {
  176.   return old(arg1, arg2, base);
  177.   }
  178.   
  179.   ********************************************/
  180.  
  181. /*
  182.  * These are the generic patch routines.
  183.  * They handle most patches automatically.
  184.  */
  185.  
  186. #define PATHSIZE    512L    /* enough for most purposes? */
  187.  
  188. /* 1 args, convert arg in d1 */
  189. LONG ASM Wedge11 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(a6) struct Library *),
  190.                   REG(d1) UBYTE *arg1, 
  191.                   REG(a6) struct Library *base)
  192. {
  193.     struct SignalSemaphore *jt;
  194.     UBYTE *newpath;
  195.     LONG rc = 0;
  196.     
  197.     if (jt = FindSemaphore(UnixDirsJTName))
  198.     {
  199.         ObtainSemaphoreShared(jt);
  200.         
  201.         if (newpath = AllocVec(PATHSIZE, 0L))
  202.         {
  203.             if (adjustpath(arg1, newpath, PATHSIZE))
  204.                 rc = dosroutine(newpath, base);
  205.             else
  206.                 rc = dosroutine(arg1, base);
  207.             
  208.             FreeVec(newpath);
  209.         }
  210.         else SetIoErr(ERROR_NO_FREE_STORE);
  211.         
  212.         ReleaseSemaphore(jt);
  213.     }
  214.     return rc;
  215. }
  216.  
  217. /* 2 args, convert arg in d1 */
  218. LONG ASM Wedge21 (REG(a0) LONG (*ASM dosroutine)(REG(d1) UBYTE *, REG(d2) LONG, REG(a6) struct Library *),
  219.                   REG(d1) UBYTE *arg1,
  220.                   REG(d2) LONG arg2, 
  221.                   REG(a6) struct Library *base)
  222. {
  223.     struct SignalSemaphore *jt;
  224.     UBYTE *newpath;
  225.     LONG rc = 0;
  226.     
  227.     if (jt = FindSemaphore(UnixDirsJTName))
  228.     {
  229.         ObtainSemaphoreShared(jt);
  230.         
  231.         if (newpath = AllocVec(PATHSIZE, 0L))
  232.         {
  233.             if (adjustpath(arg1, newpath, PATHSIZE))
  234.                 rc = dosroutine(newpath, arg2, base);
  235.             else
  236.                 rc = dosroutine(arg1, arg2, base);
  237.             FreeVec(newpath);
  238.         }
  239.         else SetIoErr(ERROR_NO_FREE_STORE);
  240.         
  241.         ReleaseSemaphore(jt);
  242.     }
  243.     return rc;
  244. }
  245.  
  246. /* 2 args, convert arg in d2 */
  247.  
  248. LONG ASM Wedge22 (REG(a0) LONG (*ASM dosroutine)(REG(d1) LONG, REG(d2) UBYTE *, REG(a6) struct Library *),
  249.                   REG(d1) LONG arg1,
  250.                   REG(d2) UBYTE *arg2, 
  251.                   REG(a6) struct Library *base)
  252. {
  253.     struct SignalSemaphore *jt;
  254.     UBYTE *newpath;
  255.     LONG rc = 0;
  256.     
  257.     if (jt = FindSemaphore(UnixDirsJTName))
  258.     {
  259.         ObtainSemaphoreShared(jt);
  260.         
  261.         if (newpath = AllocVec(PATHSIZE, 0L))
  262.         {
  263.             if (adjustpath(arg2, newpath, PATHSIZE))
  264.                 rc = dosroutine(arg1, newpath, base);
  265.             else
  266.                 rc = dosroutine(arg1, arg2, base);
  267.             
  268.             FreeVec(newpath);
  269.         }
  270.         else SetIoErr(ERROR_NO_FREE_STORE);
  271.         
  272.         ReleaseSemaphore(jt);
  273.     }
  274.     return rc;
  275. }
  276.  
  277. #define PATCH11(name) \
  278.     SAVEDS LONG ASM \
  279.     new## name(REG(d1) UBYTE *arg1, \
  280.                REG(a6) struct Library *base) \
  281. { return Wedge11(old## name, arg1, base); }
  282.  
  283. #define PATCH21(name) \
  284.     SAVEDS LONG ASM \
  285.     new## name(REG(d1) UBYTE *arg1, REG(d2) LONG arg2, \
  286.                REG(a6) struct Library *base) \
  287. { return Wedge21(old## name, arg1, arg2, base); }
  288.  
  289. #define PATCH22(name) \
  290.     SAVEDS LONG ASM \
  291.     new## name(REG(d1) LONG arg1, REG(d2) UBYTE *arg2, \
  292.                REG(a6) struct Library *base) \
  293. { return Wedge22(old## name, arg1, arg2, base); }
  294.  
  295. PATCH22(AssignLate)
  296. PATCH22(AssignPath)
  297. PATCH11(CreateDir)
  298. PATCH11(DeleteFile)
  299. PATCH11(LoadSeg)
  300. PATCH21(Lock)
  301. PATCH21(MatchFirst)
  302. PATCH21(NewLoadSeg)
  303. PATCH21(Open)
  304. PATCH21(SetComment)
  305. PATCH21(SetFileDate)
  306. PATCH21(SetProtection)
  307.  
  308. /*** And the following routines are handmade ***/
  309.  
  310. SAVEDS LONG ASM
  311.     newRename(REG(d1) UBYTE *oldname, REG(d2) UBYTE *newname,
  312.               REG(a6) struct Library *base)
  313. {
  314.     struct SignalSemaphore *jt;
  315.     UBYTE *from, *to;
  316.     LONG rc = 0;
  317.     
  318.     if (jt = FindSemaphore(UnixDirsJTName))
  319.     {
  320.         ObtainSemaphoreShared(jt);
  321.         
  322.         if (from = AllocVec(PATHSIZE, 0L))
  323.         {
  324.             adjustpath(oldname, from, PATHSIZE);
  325.             if (to = AllocVec(PATHSIZE, 0L))
  326.             {
  327.                 adjustpath(newname, to, PATHSIZE);
  328.                 rc = oldRename(from, to, base);
  329.                 FreeVec(to);
  330.             }
  331.             else SetIoErr(ERROR_NO_FREE_STORE);
  332.             FreeVec(from);
  333.         }
  334.         else SetIoErr(ERROR_NO_FREE_STORE);
  335.         
  336.         ReleaseSemaphore(jt);
  337.     }
  338.     return rc;
  339. }
  340.  
  341.  
  342. /* a bit more suspect this; will buflen be big enough given a . substitution? */
  343. SAVEDS LONG ASM
  344.     newParsePattern(REG(d1) UBYTE *pat, 
  345.                     REG(d2) UBYTE *buf, 
  346.                     REG(d3) LONG buflen,
  347.                     REG(a6) struct Library *base)
  348. {
  349.     struct SignalSemaphore *jt;
  350.     UBYTE *newpat;
  351.     LONG rc = 0;
  352.     
  353.     if (jt = FindSemaphore(UnixDirsJTName))
  354.     {
  355.         ObtainSemaphoreShared(jt);
  356.         
  357.         if (newpat = AllocVec(PATHSIZE, 0L))
  358.         {
  359.             adjustpath(pat, newpat, PATHSIZE);
  360.             rc = oldParsePattern(newpat, buf, buflen, base);
  361.             FreeVec(newpat);
  362.         }
  363.         else SetIoErr(ERROR_NO_FREE_STORE);
  364.         
  365.         ReleaseSemaphore(jt);
  366.     }
  367.     return rc;
  368. }
  369.  
  370.  
  371. SAVEDS LONG ASM
  372.     newMakeLink (REG(d1) UBYTE *name, 
  373.                  REG(d2) LONG dest,
  374.                  REG(d3) LONG soft,
  375.                  REG(a6) struct Library *base)
  376. {
  377.     struct SignalSemaphore *jt;
  378.     UBYTE *from, *to;
  379.     LONG rc = 0;
  380.     
  381.     if (jt = FindSemaphore(UnixDirsJTName))
  382.     {
  383.         ObtainSemaphoreShared(jt);
  384.         
  385.         if (from = AllocVec(PATHSIZE, 0L))
  386.         {
  387.             adjustpath(name, from, PATHSIZE);
  388.             if (soft)
  389.             {
  390.                 /* dest points to a null-terminated path string */
  391.                 if (to = AllocVec(PATHSIZE, 0L))
  392.                 {
  393.                     adjustpath((STRPTR)dest, to, PATHSIZE);
  394.                     rc = oldMakeLink(from, (LONG)to, soft, base);
  395.                     FreeVec(to);
  396.                 }
  397.                 else SetIoErr(ERROR_NO_FREE_STORE);
  398.             }
  399.             else
  400.             {
  401.                 /* dest is a lock (BPTR) */
  402.                 rc = oldMakeLink(from, dest, soft, base);
  403.             }
  404.             FreeVec(from);
  405.         }
  406.         else SetIoErr(ERROR_NO_FREE_STORE);
  407.         
  408.         ReleaseSemaphore(jt);
  409.     }
  410.     return rc;
  411. }
  412.  
  413.  
  414.  
  415.  
  416. /*
  417.  * Routine to convert a UNIX-style path to an AmigaDOS path.
  418.  * A UNIX-style path is understood here as follows:
  419.  * 
  420.  *  leading . means current dir; like "", but filled in explicitly
  421.  *  ../ means /
  422.  *  ..  means /
  423.  * 
  424.  * Written as part of UnixDirs2, a (to be written) system patch which allows
  425.  * use of UNIX-style paths everywhere.
  426.  * 
  427.  * Martin W. Scott,  8 January 1993
  428.  */
  429.  
  430.  
  431. /* insert $cwd into s, return pointer to next free char */
  432. SAVEDS char *
  433.     insertcwd(char *s, LONG len)
  434. {
  435.     if (NameFromLock(((struct Process *)(((struct ExecBase *)SysBase)->ThisTask))->pr_CurrentDir, s, len))
  436.     {
  437.         while (*s)
  438.             s++;
  439.     }
  440.     return s;
  441. }
  442.  
  443. /* adjust path from UNIX-style to Amiga-style */
  444. /* TO DO: length checking when building new path */
  445.  
  446. SAVEDS BOOL
  447.     adjustpath(UBYTE *path, UBYTE *newpath, LONG len)
  448. {
  449.     UBYTE *s, *t;
  450.     char *origpath = path;
  451.     
  452.     s = newpath;
  453.     
  454.     if (path == NULL)   /* bypass */
  455.         return FALSE;
  456.     
  457.     if (slashdir && (path[0] == '/'))
  458.     {
  459.         path[0]=':';   /* to accommodate unix-style root paths */
  460.     }
  461.     
  462.     if (t = strchr(path, ':'))      /* check for ':' in path */
  463.     {
  464.         t++;                /* copy device component */
  465.         while (path < t)
  466.             *s++ = *path++;
  467.     }
  468.     else if (path[0] == '.')        /*** translate '.' to $cwd ***/
  469.     {
  470.         if (!path[1])           /* only "." */
  471.         {
  472.             s = insertcwd(s, len);
  473.             path++;         /* path[0] == '\0' - STOP */
  474.         }
  475.         else if (path[1] == '/')    /* initial component is $cwd */
  476.         {
  477.             s = insertcwd(s, len);
  478.             if (*(s-1) != ':')
  479.                 *s++ = '/'; /* copy '/', increment pointers */
  480.             path += 2;
  481.         }
  482.     }
  483.     
  484.     while (path[0])         /*** copy remainder of path ***/
  485.     {
  486.         if ((path[0] == '.') && (path[1] == '.'))
  487.         {
  488.             if (path[2] == '/') /* just skip "..", copying '/' */
  489.             {
  490.                 path += 2;
  491.                 *s++ = *path++;
  492.             }
  493.             else if (!path[2] )  /* append '/' and stop */
  494.             {
  495.                 if ((path == origpath) ||
  496.                     (*(path-1) == '/') ||
  497.                     (*(path-1) == ':'))
  498.                 {
  499.                     path += 2;
  500.                     *s++ = '/';
  501.                 }
  502.                 else 
  503.                 {
  504.                     *s++ = *path++;
  505.                     *s++ = *path++;
  506.                 }
  507.             }
  508.             else *s++ = *path++;
  509.         }
  510.         else *s++ = *path++;
  511.     }
  512.     *s = '\0';
  513.     
  514.     return TRUE;
  515. }
  516.